import React, { useEffect, useRef } from 'react';
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { GUI } from 'lil-gui';
import blue from '@/assets/material/blue.jpg';
import pink from '@/assets/material/pink.jpeg';
import sun from '@/assets/material/sun.jpg';
import wood from '@/assets/material/wood.jpeg';

const guiParam = {
  color: 0xffff00,
};
export default function index() {
  const mountRef = useRef(null);
  useEffect(() => {
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(
      75,
      window.innerWidth / window.innerHeight,
      0.1,
      1000
    );
    camera.position.set(0, 0, 8);
    scene.add(camera);
    // 环境光
    const ambientLight = new THREE.AmbientLight(0xffffff, 1);
    scene.add(ambientLight);
    const pointLight = new THREE.PointLight(0xffffff, 20);
    pointLight.position.set(4, 5, 1);
    scene.add(pointLight);
    // 纹理
    const woodTexture = new THREE.TextureLoader().load(wood);
    const blueTexture = new THREE.TextureLoader().load(blue);
    const pinkTexture = new THREE.TextureLoader().load(pink);
    const sunTexture = new THREE.TextureLoader().load(sun);

    // 材质
    // 1、网格基础材质 MeshBasicMaterial
    // const material = new THREE.MeshBasicMaterial({ map: woodTexture });
    // 2、网格法线材质 MeshNormalMaterial  法线：垂直于表面的向量 法线作用：光照、阴影、反射
    // const material = new THREE.MeshNormalMaterial({
    // });
    // material.flatshading = true; // 平面着色
    // 3、网格Matcap材质 MeshMatcapMaterial 可以模拟光照效果
    // const material = new THREE.MeshMatcapMaterial();
    // material.matcap = woodTexture; // 设置Matcap材质 需要设置matcap属性
    // 4、网格深度材质 MeshDepthMaterial 可以模拟光照效果 深度：相机到物体的距离 靠近相机近点为白色 远离相机为黑色
    // const material = new THREE.MeshDepthMaterial();
    // 5、网格 Lambert 材质 MeshLambertMaterial 需要添加光源才能看到效果  Lambert光照模型 漫反射
    // const material = new THREE.MeshLambertMaterial();
    // material.mapcap = woodTexture;
    // 6、网格 Phong 材质 MeshPhongMaterial 需要添加光源才能看到效果  Phong光照模型 高光 比Lamber更平滑
    // const material = new THREE.MeshPhongMaterial();
    // material.mapcap = woodTexture;
    // material.specular = new THREE.Color(0x1188ff); // 设置高光颜色
    // 7、网格卡通材质 MeshToonMaterial 需要添加光源才能看到效果
    // const material = new THREE.MeshToonMaterial();
    // 8、网格标准材质 MeshStandardMaterial  标准光照模型 高光 比Phong更平滑
    const material = new THREE.MeshStandardMaterial();
    material.gradientmap = woodTexture; // 设置渐变贴图  可以设置多个渐变贴图  会根据光照强度进行混合

    const sphere = new THREE.Mesh(
      new THREE.SphereGeometry(1, 32, 32),
      material
    );
    sphere.position.x = -4;
    const plane = new THREE.Mesh(
      new THREE.PlaneGeometry(1, 1, 32, 32),
      material
    );
    plane.position.x = 4;
    const torus = new THREE.Mesh(
      new THREE.TorusGeometry(1, 0.35, 32, 32),
      material
    );
    scene.add(sphere, plane, torus);

    const renderer = new THREE.WebGLRenderer();
    mountRef.current.appendChild(renderer.domElement);
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.render(scene, camera);

    const gui = new GUI();
    gui.addColor(guiParam, 'color').onChange((value) => {
      material.color.set(value);
    });

    const controls = new OrbitControls(camera, mountRef.current);
    const animate = () => {
      controls.update();
      renderer.render(scene, camera);
      requestAnimationFrame(animate);
    };
    animate();
  }, []);
  return <div ref={mountRef} />;
}
